from functools import wraps
from jose import jwt, JWTError, ExpiredSignatureError

from django.http import JsonResponse
from django.conf import settings

from gongyequ.models import User


def login_required():
    """
    必须登录才能访问
    """

    def decorator(viewfunc):
        @wraps(viewfunc)
        def wrapper(request, *args, **kwargs):
            token = request.META.get('HTTP_AUTHORIZATION')
            if not token:
                return JsonResponse(dict(meaasge='missing "Bearer Token" header'))

            try:
                token = token.replace('Bearer ', '')
                jwt.decode(token, settings.SECRET_KEY)
            except ExpiredSignatureError:
                return JsonResponse(dict(message='token 已过期，请重新登录', status=False, code=401))
            except JWTError:
                return JsonResponse(dict(message='bad token', status=False, code=401))

            return viewfunc(request, *args, **kwargs)

        return wrapper

    return decorator


def permission_required(perm):
    """
    必须拥有某个权限才能访问
    """

    def decorator(viewfunc):
        @wraps(viewfunc)
        def wrapper(request, *args, **kwargs):
            token = request.META.get('HTTP_AUTHORIZATION')
            if not token:
                return JsonResponse(dict(meaasge='missing "Bearer Token" header'))

            try:
                token = token.replace('Bearer ', '')
                jwt_token = jwt.decode(token, settings.SECRET_KEY)
                user = User.objects.get(id=jwt_token.get('sub'))
                if not user.has_permission(perm):
                    return JsonResponse(dict(message='forbidden', status=False, code=403))
            except User.DoesNotExist:
                return JsonResponse(dict(message='not found', status=False, code=400))
            except ExpiredSignatureError:
                return JsonResponse(dict(message='token 已过期，请重新登录', status=False, code=401))
            except JWTError:
                return JsonResponse(dict(message='bad token', status=False, code=401))

            return viewfunc(request, *args, **kwargs)

        return wrapper

    return decorator
